﻿using System;
using System.Text;
using System.Windows.Forms;
using jn.Segurity.Cryptography2;

namespace ik.Security
{
    #region "enEncryption"
    /// <summary>
    /// enum crypt/decrypt
    /// </summary>
    public enum enEncryption
    {
        /// <summary>
        /// crypt text
        /// </summary>
        Crypt = 0,
        /// <summary>
        /// decrypt text
        /// </summary>
        Decrypt = 1
    }
    #endregion

    public partial class Password : UserControl
    {
        /// <summary>
        /// key propertie
        /// </summary>
        public String Key { private get; set; }

        public Password()
        {
            InitializeComponent();
        }

        #region "Encrypt"
        /// <summary>
        /// encrypt text
        /// </summary>
        /// <param name="text">text to encrypt</param>
        /// <returns>String</returns>
        public String Encrypt(String text)
        {
            try
            {
                return Encrypt(text, Key);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// encrypt text
        /// </summary>
        /// <param name="text">text to encrypt</param>
        /// <param name="key">key to encrypt</param>
        /// <returns>String</returns>
        public String Encrypt(String text, String key)
        {
            try
            {
                if (text.Trim() == "" || key.Trim() == "")
                    throw new Exception("Invalid password or key");
                return JCript.Cript(text, key);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion 

        #region "Decrypt"
        /// <summary>
        /// decrypt text
        /// </summary>
        /// <param name="text">text to decrypt</param>
        /// <returns>String</returns>
        public String Decrypt(String text)
        {
            try
            {
                return Decrypt(text, Key);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// decrypt text
        /// </summary>
        /// <param name="text">text to decrypt</param>
        /// <param name="key">key to decrypt</param>
        /// <returns>String</returns>        
        public String Decrypt(String text, String key)
        {
            try
            {
                if (text.Trim() == "" || key.Trim() == "")
                    throw new Exception("Invalid password or key");
                return JCript.Decript(text, key);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region "MD5Hash"
        /// <summary>
        /// create md5 hash - encoding: ISO-8859-1
        /// </summary>
        /// <param name="text">text</param>
        /// <returns>String</returns>
        public String MD5Hash(String text)
        {
            StringBuilder _s = new StringBuilder();
            System.Security.Cryptography.MD5CryptoServiceProvider _cs = new System.Security.Cryptography.MD5CryptoServiceProvider();
            Byte[] _bs = Encoding.GetEncoding("ISO-8859-1").GetBytes(text);
            _bs = _cs.ComputeHash(_bs);
            foreach (Byte _b in _bs)
                _s.Append(_b.ToString("x2").ToLower());
            return _s.ToString();
        }
        #endregion

        #region "CrypBase64"
        /// <summary>
        /// simple crypt and decrypt base 64
        /// </summary>
        /// <param name="text">text</param>
        /// <param name="crypt">enum Crypt/Decrypt</param>
        /// <returns>String</returns>
        /// <code>Crypto("Texto", enEncryption.Crypt)</code>
        public String CrypBase64(String text, enEncryption crypt)
        {
            try
            {
                if (crypt == enEncryption.Crypt)
                    return Convert.ToBase64String(Encoding.ASCII.GetBytes(text));
                else
                    return Encoding.ASCII.GetString(Convert.FromBase64String(text));
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion
    }
}


#region "cript"
namespace jn.Segurity.Cryptography2
{
    public static class JCript
    {
        private static jn.Segurity.Cryptography.JCriptAlgorithm jcript;

        static JCript()
        {
            jcript = new jn.Segurity.Cryptography.JCriptAlgorithm();
        }

        public static String Cript(String texto, String chave)
        {
            return jcript.Encript(texto, chave);
        }

        public static String Decript(String texto, String chave)
        {
            return jcript.Decript(texto, chave);
        }

    }
}

#endregion

#region "JCriptAlgorithm"
namespace jn.Segurity.Cryptography
{
    public class JCriptAlgorithm
    {
        public String Chave { protected get; set; }
        public Boolean CaixaAlta { get; set; }
        public String Encript(String texto)
        {
            return Encript(texto, this.Chave);
        }
        public String Encript(String texto, String chave)
        {
            this.Chave = chave;
            return encript(texto, this.Chave);
        }
        public String Decript(String texto)
        {
            return Decript(texto, this.Chave);
        }
        public String Decript(String texto, String chave)
        {
            return decript(texto, chave);
        }
        #region "Métodos privados para usar ofucador de código"

        private String encript(String texto, String chave)
        {
            Int32 keyLen = chave.Length - 1;
            Int32 keyPos = 0;
            Int32 offset = 0;
            String dest = "";
            Int32 srcPos = 0;
            Int32 srcAsc = 0;
            Int32 range = 256;

            Random rnd = new Random();

            offset = rnd.Next(range);
            dest = offset.ToString("x2");
            for (srcPos = 0; srcPos < texto.Length; ++srcPos)
            {
                srcAsc = (Convert.ToByte(texto.ToCharArray()[srcPos]) + offset) % 255;

                if (keyPos < keyLen)
                    keyPos += 1;
                else
                    keyPos = 0;

                srcAsc = srcAsc ^ Convert.ToByte(chave.ToCharArray()[keyPos]);
                dest = dest + srcAsc.ToString("x2");
                offset = srcAsc;
            }

            if (this.CaixaAlta)
                dest = dest.ToUpper();

            return dest;
        }

        private String decript(String texto, String chave)
        {
            Int32 keyLen = chave.Length - 1;
            Int32 keyPos = 0;
            Int32 offset = 0;
            String dest = "";
            Int32 srcPos = 0;
            Int32 srcAsc = 0;
            Int32 tmpsrcAsc = 0;
            Byte[] temp = new Byte[1];

            offset = Convert.ToByte(texto.Substring(0, 2), 16);
            srcPos = 2;

            do
            {
                srcAsc = Convert.ToByte(texto.Substring(srcPos, 2), 16);
                if (keyPos < keyLen)
                    keyPos += 1;
                else
                    keyPos = 0;

                tmpsrcAsc = srcAsc ^ Convert.ToByte(chave.ToCharArray()[keyPos]);
                if (tmpsrcAsc <= offset)
                    tmpsrcAsc = 255 + tmpsrcAsc - offset;
                else
                    tmpsrcAsc = tmpsrcAsc - offset;

                temp[0] = Convert.ToByte(tmpsrcAsc);
                dest += System.Text.Encoding.GetEncoding("ISO-8859-1").GetString(temp);
                offset = srcAsc;
                srcPos += 2;
            } while (srcPos < texto.Length);


            return dest;

        }

        #endregion
    }
}


#endregion
